import {RouteReuseStrategy, ActivatedRouteSnapshot, DetachedRouteHandle} from '@angular/router';

export class SimpleReuseStrategy implements RouteReuseStrategy {

  public static handlers: { [key: string]: DetachedRouteHandle } = {}

  private static waitDelete: string | null

  /** 表示对所有路由允许复用 如果你有路由不想利用可以在这加一些业务逻辑判断 */
  public shouldDetach(route: ActivatedRouteSnapshot): boolean {
    return Boolean(route.data.keep);
  }

  /** 当路由离开时会触发。按path作为key存储路由快照&组件当前实例对象 */
  public store(route: ActivatedRouteSnapshot, handle: DetachedRouteHandle): void {
    if (SimpleReuseStrategy.waitDelete && SimpleReuseStrategy.waitDelete == SimpleReuseStrategy.getRouteUrl(route)) {
      //如果待删除是当前路由则不存储快照
      SimpleReuseStrategy.waitDelete = null
      return;
    }
    SimpleReuseStrategy.handlers[SimpleReuseStrategy.getRouteUrl(route)] = handle
  }

  /** 若 path 在缓存中有的都认为允许还原路由 */
  public shouldAttach(route: ActivatedRouteSnapshot): boolean {
    return !!SimpleReuseStrategy.handlers[SimpleReuseStrategy.getRouteUrl(route)]
  }

  /** 从缓存中获取快照，若无则返回nul */
  public retrieve(route: ActivatedRouteSnapshot): DetachedRouteHandle{
    return SimpleReuseStrategy.handlers[SimpleReuseStrategy.getRouteUrl(route)]
  }

  /** 进入路由触发，判断是否同一路由 */
  public shouldReuseRoute(future: ActivatedRouteSnapshot, curr: ActivatedRouteSnapshot): boolean {
    return future.routeConfig === curr.routeConfig &&
      JSON.stringify(future.params) == JSON.stringify(curr.params);
  }

  private static getRouteUrl(route: ActivatedRouteSnapshot) {
    const url = SimpleReuseStrategy.getFullRouteURL(route);
    return url.replace(/\//g, '_')
  }

  private static getRouteUrlPath(route: ActivatedRouteSnapshot) {
    return route.url.map(urlSegment => urlSegment.path);
  }

  // 获取当前路由url
  private static getFullRouteURL(route: ActivatedRouteSnapshot): string {
    const { pathFromRoot } = route;
    let fullRouteUrlPath: string[] = [];
    pathFromRoot.forEach((item: ActivatedRouteSnapshot) => {
      fullRouteUrlPath = fullRouteUrlPath.concat( SimpleReuseStrategy.getRouteUrlPath(item));
    });
    return `/${fullRouteUrlPath.join('/')}`;
  }

  public static deleteRouteSnapshot(name: string): void {
    if (SimpleReuseStrategy.handlers[name]) {
      delete SimpleReuseStrategy.handlers[name];
    } else {
      SimpleReuseStrategy.waitDelete = name;
    }
  }
}
